from get_ip import get_host_ip
from xmlrpc.client import Boolean, boolean
import uvicorn
from datetime import datetime
from os import name
import sys
from typing import Optional
from fastapi import FastAPI, Request
from pathlib import Path
from pydantic import BaseModel
from fastapi.responses import FileResponse, Response, JSONResponse, HTMLResponse
from pydantic.types import Json
import requests
import json
from fastapi.staticfiles import StaticFiles
# app.mount("/files", StaticFiles(directory='../docs/files/'), name="files")


class Config(BaseModel):
    base_url: str
    root_dir: str
    port: str
    print_url: bool = False
    print_headers: bool = False
    print_params: bool = False
    print_body: bool = False
    print_response: bool = False
    prox: dict

config: Config = None
app = FastAPI()

def  request_interceptor(method:str="get"):
    def decorate(func):
        async def wrap(url,request:Request):
            # print(f"{ config.base_url }/{ url }")
            target_url = f"{ config.base_url }/{ url }"
            headers = {}
            # for (k,v) in request.headers.items():
                # headers[str(k)] = v
            prox_item = config.prox.get(url)
            if prox_item and prox_item.get("headers"):
                headers = prox_item["headers"]
            r:requests.Response = await func(target_url,request,headers)
            print_url = prox_item.get("print_url") if prox_item else config.print_url
            print_headers = prox_item.get(
                "print_headers") if prox_item else config.print_headers
            print_params = prox_item.get(
                "print_params") if prox_item else config.print_params
            print_body = prox_item.get(
                "print_body")  if prox_item else config.print_body
            if  method != "post":
                print_body = False
            print_response = prox_item.get(
                "print_response") if prox_item else config.print_response
            if print_url:
                print(f"get url:{r.url}")
            if print_headers:
                print(f"headers:{r.headers}")
                # print(f"request headers:{request.headers}")
            if print_params:
                print(f"params:{ request.query_params }")
            if print_body:
                body = await request.body()
                print(f"body:{ body }")
            if print_response:
                print("response: "+r.text)
            if prox_item :
                if prox_item.get("type") == 1:
                    return HTMLResponse(r.content)
                elif prox_item.get("type") == 2:
                    content = Path(f"{config.root_dir}/{prox_item['data']}").read_text()
                    return json.loads(content)
            return Response(r.content, r.status_code, r.headers)
        return wrap
    return decorate
@request_interceptor(method="get")
async def do_get(target_url, request:Request,headers):
    r = requests.get(target_url,
                     params=request.query_params, headers=headers)
    return r


@request_interceptor(method="post")
async def do_post(target_url, request,headers):
    body = await request.body()
    r = requests.post(target_url, data=body.decode(
        "utf-8"), headers=headers)
    return r


@app.get("/{filepath:path}")
async def app_get(filepath: str, request: Request):
    return await do_get(f"{filepath}", request)


@app.post("/{filepath:path}")
async def app_post(filepath: str, request: Request):
    return await do_post(f"{filepath}", request)


if __name__ == "__main__":
    config = Config.parse_file(sys.argv[1])
    uvicorn.run(app,host=get_host_ip(), port=config.port)
   
